const { Service } = require("egg");

class UserService extends Service {
  /**
   * 手机密码登录
   * @param {*} mobile
   * @param {*} password
   */
  async loginByAccount(mobile, password) {
    // 查询是否存在该手机号
    const user = await this.findByMobile(mobile);
    // 如果不存在
    if (!user) {
      this.ctx.throw("404", "用户不存在");
    }
    // 存在，检查密码是否正确
    if (user.password !== password) {
      this.ctx.throw("404", "用户密码不匹配");
    }
    // 去除敏感字段
    delete user.password;
    // 生成 token
    const token = this.ctx.helper.genToken({ ...user });
    // 获取用户详细信息
    const profile = await this.getUserDetail(user.id);
    // 查询权限id
    const menus = await this.getMenus(user.id);
    // 返回数据
    return { token, profile, menus };
  }

  /**
   * 根据手机号获取用户
   * @param {*} mobile
   */
  async findByMobile(mobile) {
    const sql = "select * from user where mobile = ? limit 0, 1";
    const params = [mobile];
    const res = await this.app.mysql.query(sql, params);
    return res[0];
  }

  /**
   * 获取前端路由权限
   * @param {*} id
   */
  async getMenus(id) {
    const sql = `
            select acl.id
            from acl
                join r_role_acl on acl.id = r_role_acl.acl_id
                join r_user_role on r_role_acl.role_id = r_user_role.role_id
            where acl.type = 1 and r_user_role.user_id = ?;
        `;
    const params = [id];
    const res = await this.app.mysql.query(sql, params);
    return res.map((item) => item.id);
  }

  /**
   * 获取用户详细信息
   * @param {*} id
   */
  async getUserDetail(id) {
    const sql = `
            select u.id, u.mobile, u.nickname, u.email, u.create_time, r.id as role_id, r.name as role_name
            from user as u
                join r_user_role as rur on u.id = rur.user_id
                join role as r on rur.role_id = r.id
            where u.id = ?;
        `;
    const params = [id];
    const res = await this.app.mysql.query(sql, params);
    return res;
  }

  /**
   * 添加用户
   * @param {string} username
   * @param {string} password
   * @param {string} relname
   */
  async create({ username, password, relname }) {
    let sql = `insert into user (username, password, relname) values (?, ?, ?)`;
    let params = [username, password, relname];
    return await this.app.mysql.query(sql, params);
  }

  /**
   * 添加用户角色
   * @param {number} uid
   * @param {number} rid
   */
  async saveRole(uid, rid) {
    let sql = `insert into r_user_role (uid, rid) values (?, ?)`;
    let params = [uid, rid];
    return await this.app.mysql.query(sql, params);
  }

  /**
   * 根据用户名，查询用户
   * @param {string} username 用户名
   */
  async readByUsername(username) {
    let sql = `select * from user where username = ? limit 0, 1`;
    let params = [username];
    let res = await this.app.mysql.query(sql, params);
    return res[0];
  }

  /**
   * 根据用户id，获取用户角色（身份）信息
   * @param {number} uid 用户id
   */
  async readRoleByUid(uid) {
    let sql = `
            select r.id as rid, r.name as rname 
            from role as r 
                join r_user_role as rur on rur.rid = r.id 
            where rur.uid = ?
            limit 0, 1
        `;
    let params = [uid];
    let res = await this.app.mysql.query(sql, params);
    return res[0];
  }

  /**
   * 根据用户id，获取用户可访问的前端路由页面
   * @param {number} uid 用户id
   */
  async readMenusByUid(uid) {
    let sql = `
            select a.name, a.path
            from user as u
                join r_user_role as rur on rur.uid = u.id
                join r_role_acl as rra on rur.rid = rra.rid
                join acl as a on a.id = rra.aid
            where a.type = 1 and u.id = ?
        `;
    let params = [uid];
    return await this.app.mysql.query(sql, params);
  }

  /**
   * 根据查询参数，读取学生列表（角色是 2、3）
   * @param {object} param0 查询参数对象
   */
  async readStuListByQuery({ query, pagesize, pagenum }) {
    let select_sql =
      "select u.id as uid, u.username, u.relname, r.id as rid, r.name as rname";
    let from_sql = " from user as u";
    let join_sql = `
            join r_user_role as rur on u.id = rur.uid
            join role as r on rur.rid = r.id
        `;
    let where_sql = " where rur.rid != 1";
    let params = [];

    // 模糊查询
    if (query && query.trim()) {
      where_sql += " and (u.username like ? or u.relname like ?)";
      let likeStr = "%" + query + "%";
      params.push(likeStr, likeStr);
    }
    // 如果有分页参数，就返回分页数据
    if (!isNaN(pagesize) && !isNaN(pagenum)) {
      // 计数
      let count_sql = "select count(*) as count";
      let countArr = await this.app.mysql.query(
        count_sql + from_sql + join_sql + where_sql,
        params
      );

      // 分页数据
      let startIndex = (pagenum - 1) * pagesize;
      params.push(startIndex, parseInt(pagesize));

      // 分页 sql
      let resArr = await this.app.mysql.query(
        select_sql + from_sql + join_sql + where_sql + " limit ?, ?",
        params
      );

      return { total: countArr[0].count, list: resArr };
    }

    return await this.app.mysql.query(
      select_sql + from_sql + join_sql + where_sql,
      params
    );
  }

  /**
   * 根据用户id，获取用户的后端路由
   * @param {number} uid 用户id
   */
  async readAclsByUid(uid) {
    let sql = `
            select a.path, a.method
            from acl as a
                join r_role_acl as rra on rra.aid = a.id and a.type = 2
                join r_user_role as rur on rur.rid = rra.rid
            where rur.uid = ?
        `;
    let params = [uid];
    return await this.app.mysql.query(sql, params);
  }

  /**
   * 删除用户
   * @param {*} uid
   * @returns
   */
  async destroy(uid) {
    let sql = "delete from user where id = ?";
    let params = [uid];
    return await this.app.mysql.query(sql, params);
  }
}

module.exports = UserService;
